home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / mips / include / asm / stackframe.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  12.5 KB  |  575 lines

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
  7.  * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
  8.  * Copyright (C) 1999 Silicon Graphics, Inc.
  9.  * Copyright (C) 2007  Maciej W. Rozycki
  10.  */
  11. #ifndef _ASM_STACKFRAME_H
  12. #define _ASM_STACKFRAME_H
  13.  
  14. #include <linux/threads.h>
  15.  
  16. #include <asm/asm.h>
  17. #include <asm/asmmacro.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/asm-offsets.h>
  20.  
  21. /*
  22.  * For SMTC kernel, global IE should be left set, and interrupts
  23.  * controlled exclusively via IXMT.
  24.  */
  25. #ifdef CONFIG_MIPS_MT_SMTC
  26. #define STATMASK 0x1e
  27. #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  28. #define STATMASK 0x3f
  29. #else
  30. #define STATMASK 0x1f
  31. #endif
  32.  
  33. #ifdef CONFIG_MIPS_MT_SMTC
  34. #include <asm/mipsmtregs.h>
  35. #endif /* CONFIG_MIPS_MT_SMTC */
  36.  
  37.         .macro    SAVE_AT
  38.         .set    push
  39.         .set    noat
  40.         LONG_S    $1, PT_R1(sp)
  41.         .set    pop
  42.         .endm
  43.  
  44.         .macro    SAVE_TEMP
  45. #ifdef CONFIG_CPU_HAS_SMARTMIPS
  46.         mflhxu    v1
  47.         LONG_S    v1, PT_LO(sp)
  48.         mflhxu    v1
  49.         LONG_S    v1, PT_HI(sp)
  50.         mflhxu    v1
  51.         LONG_S    v1, PT_ACX(sp)
  52. #else
  53.         mfhi    v1
  54.         LONG_S    v1, PT_HI(sp)
  55.         mflo    v1
  56.         LONG_S    v1, PT_LO(sp)
  57. #endif
  58. #ifdef CONFIG_32BIT
  59.         LONG_S    $8, PT_R8(sp)
  60.         LONG_S    $9, PT_R9(sp)
  61. #endif
  62.         LONG_S    $10, PT_R10(sp)
  63.         LONG_S    $11, PT_R11(sp)
  64.         LONG_S    $12, PT_R12(sp)
  65.         LONG_S    $13, PT_R13(sp)
  66.         LONG_S    $14, PT_R14(sp)
  67.         LONG_S    $15, PT_R15(sp)
  68.         LONG_S    $24, PT_R24(sp)
  69.         .endm
  70.  
  71.         .macro    SAVE_STATIC
  72.         LONG_S    $16, PT_R16(sp)
  73.         LONG_S    $17, PT_R17(sp)
  74.         LONG_S    $18, PT_R18(sp)
  75.         LONG_S    $19, PT_R19(sp)
  76.         LONG_S    $20, PT_R20(sp)
  77.         LONG_S    $21, PT_R21(sp)
  78.         LONG_S    $22, PT_R22(sp)
  79.         LONG_S    $23, PT_R23(sp)
  80.         LONG_S    $30, PT_R30(sp)
  81.         .endm
  82.  
  83. #ifdef CONFIG_SMP
  84. #ifdef CONFIG_MIPS_MT_SMTC
  85. #define PTEBASE_SHIFT    19    /* TCBIND */
  86. #else
  87. #define PTEBASE_SHIFT    23    /* CONTEXT */
  88. #endif
  89.         .macro    get_saved_sp    /* SMP variation */
  90. #ifdef CONFIG_MIPS_MT_SMTC
  91.         mfc0    k0, CP0_TCBIND
  92. #else
  93.         MFC0    k0, CP0_CONTEXT
  94. #endif
  95. #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
  96.         lui    k1, %hi(kernelsp)
  97. #else
  98.         lui    k1, %highest(kernelsp)
  99.         daddiu    k1, %higher(kernelsp)
  100.         dsll    k1, 16
  101.         daddiu    k1, %hi(kernelsp)
  102.         dsll    k1, 16
  103. #endif
  104.         LONG_SRL    k0, PTEBASE_SHIFT
  105.         LONG_ADDU    k1, k0
  106.         LONG_L    k1, %lo(kernelsp)(k1)
  107.         .endm
  108.  
  109.         .macro    set_saved_sp stackp temp temp2
  110. #ifdef CONFIG_MIPS_MT_SMTC
  111.         mfc0    \temp, CP0_TCBIND
  112. #else
  113.         MFC0    \temp, CP0_CONTEXT
  114. #endif
  115.         LONG_SRL    \temp, PTEBASE_SHIFT
  116.         LONG_S    \stackp, kernelsp(\temp)
  117.         .endm
  118. #else
  119.         .macro    get_saved_sp    /* Uniprocessor variation */
  120. #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
  121.         lui    k1, %hi(kernelsp)
  122. #else
  123.         lui    k1, %highest(kernelsp)
  124.         daddiu    k1, %higher(kernelsp)
  125.         dsll    k1, k1, 16
  126.         daddiu    k1, %hi(kernelsp)
  127.         dsll    k1, k1, 16
  128. #endif
  129.         LONG_L    k1, %lo(kernelsp)(k1)
  130.         .endm
  131.  
  132.         .macro    set_saved_sp stackp temp temp2
  133.         LONG_S    \stackp, kernelsp
  134.         .endm
  135. #endif
  136.  
  137.         .macro    SAVE_SOME
  138.         .set    push
  139.         .set    noat
  140.         .set    reorder
  141.         mfc0    k0, CP0_STATUS
  142.         sll    k0, 3        /* extract cu0 bit */
  143.         .set    noreorder
  144.         bltz    k0, 8f
  145.          move    k1, sp
  146.         .set    reorder
  147.         /* Called from user mode, new stack. */
  148.         get_saved_sp
  149. #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
  150. 8:        move    k0, sp
  151.         PTR_SUBU sp, k1, PT_SIZE
  152. #else
  153.         .set    at=k0
  154. 8:        PTR_SUBU k1, PT_SIZE
  155.         .set    noat
  156.         move    k0, sp
  157.         move    sp, k1
  158. #endif
  159.         LONG_S    k0, PT_R29(sp)
  160.         LONG_S    $3, PT_R3(sp)
  161.         /*
  162.          * You might think that you don't need to save $0,
  163.          * but the FPU emulator and gdb remote debug stub
  164.          * need it to operate correctly
  165.          */
  166.         LONG_S    $0, PT_R0(sp)
  167.         mfc0    v1, CP0_STATUS
  168.         LONG_S    $2, PT_R2(sp)
  169.         LONG_S    v1, PT_STATUS(sp)
  170. #ifdef CONFIG_MIPS_MT_SMTC
  171.         /*
  172.          * Ideally, these instructions would be shuffled in
  173.          * to cover the pipeline delay.
  174.          */
  175.         .set    mips32
  176.         mfc0    v1, CP0_TCSTATUS
  177.         .set    mips0
  178.         LONG_S    v1, PT_TCSTATUS(sp)
  179. #endif /* CONFIG_MIPS_MT_SMTC */
  180.         LONG_S    $4, PT_R4(sp)
  181.         mfc0    v1, CP0_CAUSE
  182.         LONG_S    $5, PT_R5(sp)
  183.         LONG_S    v1, PT_CAUSE(sp)
  184.         LONG_S    $6, PT_R6(sp)
  185.         MFC0    v1, CP0_EPC
  186.         LONG_S    $7, PT_R7(sp)
  187. #ifdef CONFIG_64BIT
  188.         LONG_S    $8, PT_R8(sp)
  189.         LONG_S    $9, PT_R9(sp)
  190. #endif
  191.         LONG_S    v1, PT_EPC(sp)
  192.         LONG_S    $25, PT_R25(sp)
  193.         LONG_S    $28, PT_R28(sp)
  194.         LONG_S    $31, PT_R31(sp)
  195.         ori    $28, sp, _THREAD_MASK
  196.         xori    $28, _THREAD_MASK
  197.         .set    pop
  198.         .endm
  199.  
  200.         .macro    SAVE_ALL
  201.         SAVE_SOME
  202.         SAVE_AT
  203.         SAVE_TEMP
  204.         SAVE_STATIC
  205.         .endm
  206.  
  207.         .macro    RESTORE_AT
  208.         .set    push
  209.         .set    noat
  210.         LONG_L    $1,  PT_R1(sp)
  211.         .set    pop
  212.         .endm
  213.  
  214.         .macro    RESTORE_TEMP
  215. #ifdef CONFIG_CPU_HAS_SMARTMIPS
  216.         LONG_L    $24, PT_ACX(sp)
  217.         mtlhx    $24
  218.         LONG_L    $24, PT_HI(sp)
  219.         mtlhx    $24
  220.         LONG_L    $24, PT_LO(sp)
  221.         mtlhx    $24
  222. #else
  223.         LONG_L    $24, PT_LO(sp)
  224.         mtlo    $24
  225.         LONG_L    $24, PT_HI(sp)
  226.         mthi    $24
  227. #endif
  228. #ifdef CONFIG_32BIT
  229.         LONG_L    $8, PT_R8(sp)
  230.         LONG_L    $9, PT_R9(sp)
  231. #endif
  232.         LONG_L    $10, PT_R10(sp)
  233.         LONG_L    $11, PT_R11(sp)
  234.         LONG_L    $12, PT_R12(sp)
  235.         LONG_L    $13, PT_R13(sp)
  236.         LONG_L    $14, PT_R14(sp)
  237.         LONG_L    $15, PT_R15(sp)
  238.         LONG_L    $24, PT_R24(sp)
  239.         .endm
  240.  
  241.         .macro    RESTORE_STATIC
  242.         LONG_L    $16, PT_R16(sp)
  243.         LONG_L    $17, PT_R17(sp)
  244.         LONG_L    $18, PT_R18(sp)
  245.         LONG_L    $19, PT_R19(sp)
  246.         LONG_L    $20, PT_R20(sp)
  247.         LONG_L    $21, PT_R21(sp)
  248.         LONG_L    $22, PT_R22(sp)
  249.         LONG_L    $23, PT_R23(sp)
  250.         LONG_L    $30, PT_R30(sp)
  251.         .endm
  252.  
  253. #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  254.  
  255.         .macro    RESTORE_SOME
  256.         .set    push
  257.         .set    reorder
  258.         .set    noat
  259.         mfc0    a0, CP0_STATUS
  260.         li    v1, 0xff00
  261.         ori    a0, STATMASK
  262.         xori    a0, STATMASK
  263.         mtc0    a0, CP0_STATUS
  264.         and    a0, v1
  265.         LONG_L    v0, PT_STATUS(sp)
  266.         nor    v1, $0, v1
  267.         and    v0, v1
  268.         or    v0, a0
  269.         mtc0    v0, CP0_STATUS
  270.         LONG_L    $31, PT_R31(sp)
  271.         LONG_L    $28, PT_R28(sp)
  272.         LONG_L    $25, PT_R25(sp)
  273.         LONG_L    $7,  PT_R7(sp)
  274.         LONG_L    $6,  PT_R6(sp)
  275.         LONG_L    $5,  PT_R5(sp)
  276.         LONG_L    $4,  PT_R4(sp)
  277.         LONG_L    $3,  PT_R3(sp)
  278.         LONG_L    $2,  PT_R2(sp)
  279.         .set    pop
  280.         .endm
  281.  
  282.         .macro    RESTORE_SP_AND_RET
  283.         .set    push
  284.         .set    noreorder
  285.         LONG_L    k0, PT_EPC(sp)
  286.         LONG_L    sp, PT_R29(sp)
  287.         jr    k0
  288.          rfe
  289.         .set    pop
  290.         .endm
  291.  
  292. #else
  293.         .macro    RESTORE_SOME
  294.         .set    push
  295.         .set    reorder
  296.         .set    noat
  297. #ifdef CONFIG_MIPS_MT_SMTC
  298.         .set    mips32r2
  299.         /*
  300.          * We need to make sure the read-modify-write
  301.          * of Status below isn't perturbed by an interrupt
  302.          * or cross-TC access, so we need to do at least a DMT,
  303.          * protected by an interrupt-inhibit. But setting IXMT
  304.          * also creates a few-cycle window where an IPI could
  305.          * be queued and not be detected before potentially
  306.          * returning to a WAIT or user-mode loop. It must be
  307.          * replayed.
  308.          *
  309.          * We're in the middle of a context switch, and
  310.          * we can't dispatch it directly without trashing
  311.          * some registers, so we'll try to detect this unlikely
  312.          * case and program a software interrupt in the VPE,
  313.          * as would be done for a cross-VPE IPI.  To accomodate
  314.          * the handling of that case, we're doing a DVPE instead
  315.          * of just a DMT here to protect against other threads.
  316.          * This is a lot of cruft to cover a tiny window.
  317.          * If you can find a better design, implement it!
  318.          *
  319.          */
  320.         mfc0    v0, CP0_TCSTATUS
  321.         ori    v0, TCSTATUS_IXMT
  322.         mtc0    v0, CP0_TCSTATUS
  323.         _ehb
  324.         DVPE    5                # dvpe a1
  325.         jal    mips_ihb
  326. #endif /* CONFIG_MIPS_MT_SMTC */
  327.         mfc0    a0, CP0_STATUS
  328.         ori    a0, STATMASK
  329.         xori    a0, STATMASK
  330.         mtc0    a0, CP0_STATUS
  331.         li    v1, 0xff00
  332.         and    a0, v1
  333.         LONG_L    v0, PT_STATUS(sp)
  334.         nor    v1, $0, v1
  335.         and    v0, v1
  336.         or    v0, a0
  337.         mtc0    v0, CP0_STATUS
  338. #ifdef CONFIG_MIPS_MT_SMTC
  339. /*
  340.  * Only after EXL/ERL have been restored to status can we
  341.  * restore TCStatus.IXMT.
  342.  */
  343.         LONG_L    v1, PT_TCSTATUS(sp)
  344.         _ehb
  345.         mfc0    a0, CP0_TCSTATUS
  346.         andi    v1, TCSTATUS_IXMT
  347.         bnez    v1, 0f
  348.  
  349. /*
  350.  * We'd like to detect any IPIs queued in the tiny window
  351.  * above and request an software interrupt to service them
  352.  * when we ERET.
  353.  *
  354.  * Computing the offset into the IPIQ array of the executing
  355.  * TC's IPI queue in-line would be tedious.  We use part of
  356.  * the TCContext register to hold 16 bits of offset that we
  357.  * can add in-line to find the queue head.
  358.  */
  359.         mfc0    v0, CP0_TCCONTEXT
  360.         la    a2, IPIQ
  361.         srl    v0, v0, 16
  362.         addu    a2, a2, v0
  363.         LONG_L    v0, 0(a2)
  364.         beqz    v0, 0f
  365. /*
  366.  * If we have a queue, provoke dispatch within the VPE by setting C_SW1
  367.  */
  368.         mfc0    v0, CP0_CAUSE
  369.         ori    v0, v0, C_SW1
  370.         mtc0    v0, CP0_CAUSE
  371. 0:
  372.         /*
  373.          * This test should really never branch but
  374.          * let's be prudent here.  Having atomized
  375.          * the shared register modifications, we can
  376.          * now EVPE, and must do so before interrupts
  377.          * are potentially re-enabled.
  378.          */
  379.         andi    a1, a1, MVPCONTROL_EVP
  380.         beqz    a1, 1f
  381.         evpe
  382. 1:
  383.         /* We know that TCStatua.IXMT should be set from above */
  384.         xori    a0, a0, TCSTATUS_IXMT
  385.         or    a0, a0, v1
  386.         mtc0    a0, CP0_TCSTATUS
  387.         _ehb
  388.  
  389.         .set    mips0
  390. #endif /* CONFIG_MIPS_MT_SMTC */
  391.         LONG_L    v1, PT_EPC(sp)
  392.         MTC0    v1, CP0_EPC
  393.         LONG_L    $31, PT_R31(sp)
  394.         LONG_L    $28, PT_R28(sp)
  395.         LONG_L    $25, PT_R25(sp)
  396. #ifdef CONFIG_64BIT
  397.         LONG_L    $8, PT_R8(sp)
  398.         LONG_L    $9, PT_R9(sp)
  399. #endif
  400.         LONG_L    $7,  PT_R7(sp)
  401.         LONG_L    $6,  PT_R6(sp)
  402.         LONG_L    $5,  PT_R5(sp)
  403.         LONG_L    $4,  PT_R4(sp)
  404.         LONG_L    $3,  PT_R3(sp)
  405.         LONG_L    $2,  PT_R2(sp)
  406.         .set    pop
  407.         .endm
  408.  
  409.         .macro    RESTORE_SP_AND_RET
  410.         LONG_L    sp, PT_R29(sp)
  411.         .set    mips3
  412.         eret
  413.         .set    mips0
  414.         .endm
  415.  
  416. #endif
  417.  
  418.         .macro    RESTORE_SP
  419.         LONG_L    sp, PT_R29(sp)
  420.         .endm
  421.  
  422.         .macro    RESTORE_ALL
  423.         RESTORE_TEMP
  424.         RESTORE_STATIC
  425.         RESTORE_AT
  426.         RESTORE_SOME
  427.         RESTORE_SP
  428.         .endm
  429.  
  430.         .macro    RESTORE_ALL_AND_RET
  431.         RESTORE_TEMP
  432.         RESTORE_STATIC
  433.         RESTORE_AT
  434.         RESTORE_SOME
  435.         RESTORE_SP_AND_RET
  436.         .endm
  437.  
  438. /*
  439.  * Move to kernel mode and disable interrupts.
  440.  * Set cp0 enable bit as sign that we're running on the kernel stack
  441.  */
  442.         .macro    CLI
  443. #if !defined(CONFIG_MIPS_MT_SMTC)
  444.         mfc0    t0, CP0_STATUS
  445.         li    t1, ST0_CU0 | STATMASK
  446.         or    t0, t1
  447.         xori    t0, STATMASK
  448.         mtc0    t0, CP0_STATUS
  449. #else /* CONFIG_MIPS_MT_SMTC */
  450.         /*
  451.          * For SMTC, we need to set privilege
  452.          * and disable interrupts only for the
  453.          * current TC, using the TCStatus register.
  454.          */
  455.         mfc0    t0, CP0_TCSTATUS
  456.         /* Fortunately CU 0 is in the same place in both registers */
  457.         /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
  458.         li    t1, ST0_CU0 | 0x08001c00
  459.         or    t0, t1
  460.         /* Clear TKSU, leave IXMT */
  461.         xori    t0, 0x00001800
  462.         mtc0    t0, CP0_TCSTATUS
  463.         _ehb
  464.         /* We need to leave the global IE bit set, but clear EXL...*/
  465.         mfc0    t0, CP0_STATUS
  466.         ori    t0, ST0_EXL | ST0_ERL
  467.         xori    t0, ST0_EXL | ST0_ERL
  468.         mtc0    t0, CP0_STATUS
  469. #endif /* CONFIG_MIPS_MT_SMTC */
  470.         irq_disable_hazard
  471.         .endm
  472.  
  473. /*
  474.  * Move to kernel mode and enable interrupts.
  475.  * Set cp0 enable bit as sign that we're running on the kernel stack
  476.  */
  477.         .macro    STI
  478. #if !defined(CONFIG_MIPS_MT_SMTC)
  479.         mfc0    t0, CP0_STATUS
  480.         li    t1, ST0_CU0 | STATMASK
  481.         or    t0, t1
  482.         xori    t0, STATMASK & ~1
  483.         mtc0    t0, CP0_STATUS
  484. #else /* CONFIG_MIPS_MT_SMTC */
  485.         /*
  486.          * For SMTC, we need to set privilege
  487.          * and enable interrupts only for the
  488.          * current TC, using the TCStatus register.
  489.          */
  490.         _ehb
  491.         mfc0    t0, CP0_TCSTATUS
  492.         /* Fortunately CU 0 is in the same place in both registers */
  493.         /* Set TCU0, TKSU (for later inversion) and IXMT */
  494.         li    t1, ST0_CU0 | 0x08001c00
  495.         or    t0, t1
  496.         /* Clear TKSU *and* IXMT */
  497.         xori    t0, 0x00001c00
  498.         mtc0    t0, CP0_TCSTATUS
  499.         _ehb
  500.         /* We need to leave the global IE bit set, but clear EXL...*/
  501.         mfc0    t0, CP0_STATUS
  502.         ori    t0, ST0_EXL
  503.         xori    t0, ST0_EXL
  504.         mtc0    t0, CP0_STATUS
  505.         /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
  506. #endif /* CONFIG_MIPS_MT_SMTC */
  507.         irq_enable_hazard
  508.         .endm
  509.  
  510. /*
  511.  * Just move to kernel mode and leave interrupts as they are.  Note
  512.  * for the R3000 this means copying the previous enable from IEp.
  513.  * Set cp0 enable bit as sign that we're running on the kernel stack
  514.  */
  515.         .macro    KMODE
  516. #ifdef CONFIG_MIPS_MT_SMTC
  517.         /*
  518.          * This gets baroque in SMTC.  We want to
  519.          * protect the non-atomic clearing of EXL
  520.          * with DMT/EMT, but we don't want to take
  521.          * an interrupt while DMT is still in effect.
  522.          */
  523.  
  524.         /* KMODE gets invoked from both reorder and noreorder code */
  525.         .set    push
  526.         .set    mips32r2
  527.         .set    noreorder
  528.         mfc0    v0, CP0_TCSTATUS
  529.         andi    v1, v0, TCSTATUS_IXMT
  530.         ori    v0, TCSTATUS_IXMT
  531.         mtc0    v0, CP0_TCSTATUS
  532.         _ehb
  533.         DMT    2                # dmt    v0
  534.         /*
  535.          * We don't know a priori if ra is "live"
  536.          */
  537.         move    t0, ra
  538.         jal    mips_ihb
  539.         nop    /* delay slot */
  540.         move    ra, t0
  541. #endif /* CONFIG_MIPS_MT_SMTC */
  542.         mfc0    t0, CP0_STATUS
  543.         li    t1, ST0_CU0 | (STATMASK & ~1)
  544. #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  545.         andi    t2, t0, ST0_IEP
  546.         srl    t2, 2
  547.         or    t0, t2
  548. #endif
  549.         or    t0, t1
  550.         xori    t0, STATMASK & ~1
  551.         mtc0    t0, CP0_STATUS
  552. #ifdef CONFIG_MIPS_MT_SMTC
  553.         _ehb
  554.         andi    v0, v0, VPECONTROL_TE
  555.         beqz    v0, 2f
  556.         nop    /* delay slot */
  557.         emt
  558. 2:
  559.         mfc0    v0, CP0_TCSTATUS
  560.         /* Clear IXMT, then OR in previous value */
  561.         ori    v0, TCSTATUS_IXMT
  562.         xori    v0, TCSTATUS_IXMT
  563.         or    v0, v1, v0
  564.         mtc0    v0, CP0_TCSTATUS
  565.         /*
  566.          * irq_disable_hazard below should expand to EHB
  567.          * on 24K/34K CPUS
  568.          */
  569.         .set pop
  570. #endif /* CONFIG_MIPS_MT_SMTC */
  571.         irq_disable_hazard
  572.         .endm
  573.  
  574. #endif /* _ASM_STACKFRAME_H */
  575.